home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Think Class Libraries / CPixMap.p 1.0 / CPixMapPane.p < prev   
Encoding:
Text File  |  1996-02-04  |  12.3 KB  |  443 lines  |  [TEXT/PJMM]

  1. {****************************************************}
  2. {}
  3. {        CPixMap.p                                                                                                                                                                                                                }
  4. {}
  5. {        SUPERCLASS = CBitMap                                                                                                                                                                    }
  6. {}
  7. {        Copyright © 1996 Patrick C Hew. All rights reserved.                                                                        }
  8. {}
  9. {        Based on CColorBitMap.c Code by John A Love, III                                                                                        }
  10. {        email : jlove@aol.com                                                                                                                                                                            }
  11. {}
  12. {        Translated from CPixMap.cp Code by Marty R Wachter                                                                        }
  13. {        email : mrw@welchgate.welch     or afaMarty@aol.com                                                                                }
  14. {}
  15. {        The principal focus of the other files is to OVERRIDE the THINK Class Library's    }
  16. {        "CBitMap" and "CBitMapPane" classes to accomodate color.                                                            }
  17. {}
  18. {        The principal foundation of this work rests with Forrest Tanaka 's    Macintosh        }
  19. {        Technical Note #120. Other, though lesser, key points are :                                                            }
  20. {}
  21. {        •    I have introduced a new instance variable of CBitMapPane in my                                        }
  22. {                CColorBitMapPane class which I call "bitsUnderPane ". It becomes very                }
  23. {                useful when dragging objects around , vice having to take a "picture" of                 }
  24. {                the entire window or screen as Symantec 's    Art Class demo does.     I must        }
  25. {                admit , however , that I have not YET    figured out how to update this                        }
  26. {                "bitsUnderPane" CColorBitMap with a change in color depth, for example,        }
  27. {                when using the popular "Switch-A-Roo"     FKEY. Please refer to my Update            }
  28. {                method for further insight. By the way, Update works just fine    with                        }
  29. {                "itsBitMap", the on-th -top CBitMap.                                                                                                                        }
  30. {        •    I have made much more prolific comments throughout the source.                                    }
  31. {                I truly hope that they are sufficient to guide you.                                                                                    }
  32. {}
  33. {        Original Author : John A . Love , III email : jlove@aol.com                                                                }
  34. {}
  35. {        Revision History:                                                                                                                                                                                        }
  36. {}
  37. {        Version:    1.0 for TCL 1.1.3 (C)                                                                                                                                                }
  38. {        Date:             1993                                                                                                                                                                                                }
  39. {        Author:        John A Love, III     <jlove@aol.com>                                                                                                            }
  40. {        Notes:            Original release.                                                                                                                                                                }
  41. {}
  42. {        Version:    2.0 for TCL 2.0.3 (C++)                                                                                                                                        }
  43. {        Date:             10 November 1994                                                                                                                                                        }
  44. {        Author:        Marty R Wachter     <mrw@welchgate.welch.jhu.edu> or                                                }
  45. {                                                                                            <afaMarty@aol.com>                                                                                            }
  46. {        Notes:            Added support for real C++ in TCL 2.0 by adding proper,                                        }
  47. {                                    constructors, destructors, class definitions, etc… to conform to                }
  48. {                                    the TCL 2.0 changes.                                                                                                                                                    }
  49. {}
  50. {        Version:    1.0 for TCL 1.1.2 (Pascal)                                                                                                                                    }
  51. {        Date:             28 January 1996                                                                                                                                                            }
  52. {        Author:        Patrick C Hew     <phew@ucc.gu.uwa.edu.au>                                                                                }
  53. {        Notes:            Translated from CPixMap.cp.                                                                                                                            }
  54. {}
  55. {****************************************************}
  56.  
  57.  
  58. unit CPixmapPane;
  59.  
  60. interface
  61.  
  62.     uses
  63.         TCL, MoreTCL, CPixMap;
  64.  
  65.     type
  66.         DeviceOption = (kDeepestScreen, kLargestAreaScreen);
  67.  
  68.  
  69.     type
  70.         CPixMapPane = object(CBitMapPane)
  71.  
  72.                 bitsUnderPane: CPixMap;
  73.                 gdOption: DeviceOption;
  74.                 currentDepth: Integer;
  75.  
  76.                 { Construct a PixMapPane object.     }
  77.                 procedure IPixMapPane (anEnclosure: CView;
  78.                                             aSupervisor: CBureaucrat;
  79.                                             aWidth, aHeight, aHEncl, aVEncl: Integer;
  80.                                             aHSizing, aVSizing: SizingOption;
  81.                                             aBounds: LongRect;
  82.                                             aPixMap: CPixMap;
  83.                                             makePort: Boolean);
  84.  
  85.                 { Destroy a PixMapPane object, resetting all pointers. }
  86.                 procedure Free;
  87.                 override;
  88.  
  89.                 { Draw a PixMapPane. }
  90.                 procedure Draw (var area: Rect);
  91.                 override;
  92.  
  93.                 { Returns TRUE if the PixMapPane needs updating to reflect a change in }
  94.                 { screen depth. }
  95.                 function PixMapsNeedUpdating: Boolean;
  96.  
  97.                 { Returns the screen device specified by gdOption. }
  98.                 function GetScreenDevice (var globalRect: Rect): GDHandle;
  99.  
  100.                 { Display and draw a PICT resource in the PixMap. }
  101.                 procedure BlitPICTRes (hOrig, vOrig: Integer;
  102.                                             pictID: Integer;
  103.                                             drawIt: Boolean);
  104.  
  105.             end; { CPixMapPane }
  106.  
  107. implementation
  108.  
  109.     uses
  110.         LongQD;
  111.  
  112.  
  113. {****************************************************}
  114. {}
  115. {        IPixMapPane                                                                                                                                                                                                        }
  116. {}
  117. {        Construct a PixMapPane object.                                                                                                                                                }
  118. {}
  119. {****************************************************}
  120.  
  121.     procedure CPixMapPane.IPixMapPane (anEnclosure: CView;
  122.                                     aSupervisor: CBureaucrat;
  123.                                     aWidth, aHeight, aHEncl, aVEncl: Integer;
  124.                                     aHSizing, aVSizing: SizingOption;
  125.                                     aBounds: LongRect;
  126.                                     aPixMap: CPixMap;
  127.                                     makePort: Boolean);
  128.  
  129.         var
  130.             globalBoundsR: Rect;
  131.             currMaxDevice: GDHandle;
  132.             desktop: RgnHandle;
  133.  
  134.             thePixMap: CPixMap;
  135.             fi: FailInfo;
  136.  
  137.         procedure HandleMainBitmapFailure (error: Integer;
  138.                                         message: LongInt);
  139.  
  140.         begin { HandleMainBitmapFailure }
  141.             ForgetObject(itsBitMap);
  142.             itsBitMap := nil;
  143.         end; { HandleMainBitmapFailure }
  144.  
  145.         procedure HandleUnderBitmapFailure (error: Integer;
  146.                                         message: LongInt);
  147.  
  148.         begin { HandleUnderBitmapFailure }
  149.             ForgetObject(bitsUnderPane);
  150.             bitsUnderPane := nil;
  151.             ForgetObject(itsBitMap);
  152.             itsBitMap := nil;
  153.         end; { HandleUnderBitmapFailure }
  154.  
  155.     begin { IPixMapPane}
  156.         itsBitMap := nil;
  157.  
  158.         IPanorama(anEnclosure, aSupervisor, aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing);
  159.  
  160.         bounds := aBounds;
  161.         position.h := bounds.left;
  162.         position.v := bounds.top;
  163.  
  164.         itsBitmap := nil;
  165.         bitsUnderPane := nil;
  166.         gdOption := kDeepestScreen;
  167.  
  168.         { Since FrameToGlobalR accesses CPane's hOrigin and vOrigin. }
  169.         Prepare;
  170.         FrameToGlobalR(aBounds, globalBoundsR);
  171.  
  172.         if not gSystem.hasColorQD then begin
  173.             currentDepth := 1;
  174.         end { if }
  175.         else begin
  176.             currMaxDevice := GetScreenDevice(globalBoundsR);
  177.             if currMaxDevice <> nil then begin
  178.                 currentDepth := currMaxDevice^^.gdPMap^^.pixelSize;
  179.             end
  180.             else begin
  181.                 FailOSErr(NilGDeviceError);
  182.             end; { else }
  183.         end; { else }
  184.  
  185.         if aPixMap = nil then begin
  186.             CatchFailures(fi, HandleMainBitmapFailure);
  187.  
  188.             new(aPixMap);
  189.             aPixMap.IPixMap(Integer(aBounds.right - aBounds.left), Integer(aBounds.bottom - aBounds.top), makePort);
  190.             itsBitmap := aPixMap;
  191.  
  192.             Success;
  193.  
  194.         { I "roll my own" bounds within IPixMap: }
  195.         { itsBitMap.SetBoundsOrigin(aBounds.left, aBounds.top); }
  196.  
  197.         end { if }
  198.         else begin
  199.             itsBitMap := aPixMap;
  200.         end; { else }
  201.  
  202.         CatchFailures(fi, HandleUnderBitmapFailure);
  203.  
  204.         new(thePixMap);
  205.         thePixMap.IPixMap(Integer(aBounds.right - aBounds.left), Integer(aBounds.bottom - aBounds.top), makePort);
  206.         bitsUnderPane := thePixMap;
  207.  
  208.         Success;
  209.  
  210.         autoRefresh := FALSE;
  211.     end; { IPixMapPane }
  212.  
  213.  
  214. {****************************************************}
  215. {}
  216. {        Free                                                                                                                                                                                                                                }
  217. {}
  218. {        Destroy a PixMapPane object, resetting all pointers.                                                                                }
  219. {}
  220. {****************************************************}
  221.  
  222.     procedure CPixMapPane.Free;
  223.  
  224.     begin { Free }
  225.         ForgetObject(bitsUnderPane);
  226.         bitsUnderPane := nil;
  227.  
  228.         { itsBitmap is disposed of in inherited method. }
  229.  
  230.         inherited Free;
  231.     end; { Free }
  232.  
  233.  
  234. {****************************************************}
  235. {}
  236. {        Draw                                                                                                                                                                                                                            }
  237. {}
  238. {        Draw a PixMapPane.                                                                                                                                                                                }
  239. {}
  240. {****************************************************}
  241.  
  242.     procedure CPixMapPane.Draw (var area: Rect);
  243.  
  244.         var
  245.             theLBounds, lArea: LongRect;
  246.             theSBounds: Rect;
  247.  
  248.             ignore: Boolean;
  249.  
  250.     begin { Draw }
  251.         if itsBitmap <> nil then begin
  252.  
  253.             if PixMapsNeedUpdating then begin
  254.                     { CPixMap(itsBitMap).Update; }
  255.                 if bitsUnderPane <> nil then begin
  256.                         { bitsUnderPane.Update; }
  257.                 end; { if }
  258.             end; { if }
  259.  
  260.             CPixMap(itsBitMap).GetBounds(theLBounds);
  261.             LongToQDRect(theLBounds, theSBounds);
  262.             ignore := SectRect(area, theSBounds, area);
  263.  
  264.             QDToFrameR(area, lArea);
  265.             CPixMap(itsBitMap).CopyFrom(lArea, lArea, nil);
  266.         end; { if }
  267.     end; { Draw }
  268.  
  269.  
  270. {****************************************************}
  271. {}
  272. {        PixMapsNeedUpdating                                                                                                                                                                            }
  273. {}
  274. {        Returns TRUE if the PixMapPane needs updating to reflect a change in                                }
  275. {        screen depth.                                                                                                                                                                                                    }
  276. {}
  277. {****************************************************}
  278.  
  279.     function CPixMapPane.PixMapsNeedUpdating: Boolean;
  280.  
  281.         var
  282.             theBoundsRect: LongRect;
  283.             globalBoundsR: Rect;
  284.             newMaxDevice: GDHandle;
  285.             newDepth: Integer;
  286.  
  287.     begin { PixMapsNeedUpdating }
  288.         if not gSystem.hasColorQD then begin
  289.             PixMapsNeedUpdating := FALSE;
  290.         end { if }
  291.         else begin
  292.             Prepare;
  293.  
  294.             CPixMap(itsBitMap).GetBounds(theBoundsRect);
  295.             FrameToGlobalR(theBoundsRect, globalBoundsR);
  296.  
  297.             newMaxDevice := GetScreenDevice(globalBoundsR);
  298.             if newMaxDevice = nil then begin
  299.                 PixMapsNeedUpdating := FALSE;
  300.             end { if }
  301.             else begin
  302.                 newDepth := newMaxDevice^^.gdPMap^^.pixelSize;
  303.                 if newDepth > currentDepth then begin
  304.                     currentDepth := newDepth;
  305.                     PixMapsNeedUpdating := TRUE;
  306.                 end { if }
  307.                 else begin
  308.                     PixMapsNeedUpdating := FALSE;
  309.                 end; { else }
  310.             end; { else }
  311.  
  312.         end; { else }
  313.     end; { PixMapsNeedUpdating }
  314.  
  315.  
  316. {****************************************************}
  317. {}
  318. {        GetScreenDevice                                                                                                                                                                                            }
  319. {}
  320. {        Returns the screen device specified by gdOption.                                                                                            }
  321. {}
  322. {****************************************************}
  323.  
  324.     function CPixMapPane.GetScreenDevice (var globalRect: Rect): GDHandle;
  325.  
  326.         var
  327.             desktop: RgnHandle;
  328.             area, maxArea: LongInt;
  329.             device, result: GDHandle;
  330.             intersection: Rect;
  331.  
  332.     begin { GetScreenDevice }
  333.         result := nil;
  334.  
  335.         { Different screen options require different algorithms. }
  336.  
  337.         if gdOption = kDeepestScreen then begin
  338.             result := GetMaxDevice(globalRect);
  339.         end { if }
  340.         else if gdOption = kLargestAreaScreen then begin
  341.  
  342.             { Get a Handle to the first GDevice in the GDevice list. }
  343.             device := GetDeviceList;
  344.  
  345.             { Keep looping until all GDevices have been checked. }
  346.             maxArea := 0;
  347.             while device <> nil do begin
  348.                 if TestDeviceAttribute(device, screenDevice) then begin
  349.                     if TestDeviceAttribute(device, screenActive) then begin
  350.                         { Do screen and passed Rect intersect? }
  351.                         if SectRect(globalRect, device^^.gdRect, intersection) then begin
  352.                             {Yup, so calculate the interection}
  353.                             area := LongInt(intersection.right - intersection.left) * LongInt(intersection.bottom - intersection.top);
  354.  
  355.                             { Keep track of largest interection area found so far. }
  356.                             if area > maxArea then begin
  357.                                 result := device;
  358.                                 maxArea := area;
  359.                             end; { if }
  360.  
  361.                         end; { if }
  362.  
  363.                         device := GetNextDevice(device);
  364.  
  365.                     end; { if }
  366.                 end; { while }
  367.  
  368.             end; { else if }
  369.         end; { else }
  370.  
  371.         if result = nil then begin
  372.         { We're literally OFF the screen, so effect a DeviceOption }
  373.         { = "kLargestAreaScreen" based on the total Desktop region. }
  374.         { Change the object's "gdOption" instance variable since }
  375.         { we may have passed "kLargestAreaScreen": }
  376.  
  377.             desktop := GetGrayRgn;
  378.             result := GetMaxDevice(desktop^^.rgnBBox);
  379.             if (result <> nil) then begin
  380.                 gdOption := kDeepestScreen;
  381.             end; { if }
  382.         end; { if }
  383.  
  384.         GetScreenDevice := result;
  385.     end; { GetScreenDevice }
  386.  
  387.  
  388. {****************************************************}
  389. {}
  390. {        BlitPICTRes                                                                                                                                                                                                            }
  391. {}
  392. {        Display and draw a PICT resource in the PixMap.                                                                                            }
  393. {}
  394. {****************************************************}
  395.  
  396.     procedure CPixMapPane.BlitPICTRes (hOrig, vOrig: Integer;
  397.                                     pictID: Integer;
  398.                                     drawIt: Boolean);
  399.  
  400.         var
  401.             r: Rect;
  402.             wide, high: Integer;
  403.             hPic: PicHandle;
  404.             savedAlloc: Boolean;
  405.  
  406.     begin
  407.         CPixMap(itsBitMap).BeginDrawing;
  408.  
  409.         {    Get the PICT from a resource. }
  410.         savedAlloc := SetAllocation(kAllocCanFail);
  411.         hPic := GetPicture(pictID);
  412.         savedAlloc := SetAllocation(savedAlloc);
  413.         FailResError;
  414.  
  415.         HNoPurge(Handle(hPic));
  416.  
  417.         {    Draw at (0,0), original size. }
  418.         r := hPic^^.picFrame;
  419.  
  420.         {    Calculate width and height. }
  421.         wide := r.right - r.left;
  422.         high := r.bottom - r.top;
  423.  
  424.         SetRect(r, 0, 0, wide, high);
  425.         OffsetRect(r, -hOrig, -vOrig);
  426.         EraseRect(r);
  427.         DrawPicture(hPic, r);
  428.  
  429.         CPixMap(itsBitMap).EndDrawing;
  430.  
  431.         { We are finished with the picture. }
  432.         HPurge(Handle(hPic));
  433.         ForgetResource(hPic);
  434.         hPic := nil;
  435.  
  436.         if drawIt then begin
  437.             LongToQDRect(bounds, r);
  438.             Draw(r);
  439.         end; { if }
  440.  
  441.     end; { BlitPICTRes }
  442.  
  443. end. { CPixMapPane }